/**
 * 
 */
package com.archerdu.apply.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.archerdu.apply.dao.OptionDAO;
import com.archerdu.apply.dao.QuestionDAO;
import com.archerdu.apply.model.Option;
import com.archerdu.apply.model.Question;
import com.archerdu.apply.service.QuestionManager;
import com.archerdu.base.dao.HibernateBaseDao;
import com.archerdu.base.exception.BussinessException;
import com.archerdu.base.service.BaseManager;
import com.archerdu.commons.constant.ErrorConstant;

/**
 * @author archer
 * @version 1.0.0
 */
public class QuestionManagerImpl extends BaseManager<Question, Integer> implements QuestionManager {

    private static final long serialVersionUID = 8596375322783640728L;

    private OptionDAO         optionDao;
    private QuestionDAO       questionDao;

    @Override
    public void delete(Question question) throws Exception {
        // 没有删除条件
        if (null == question || null == question.getId()) {
            throw new BussinessException(ErrorConstant.DELETE_ERROR);
        }
        question = questionDao.get(question.getId());

        // 要删除的对象不存在
        if (null == question) {
            throw new BussinessException(ErrorConstant.DELETE_ERROR);
        }
        Option opt = new Option();
        opt.setQuestion(question);
        List<Option> list = optionDao.findWithQuestion(opt);
        // 题目下已有选项，不能删除
        if (list.size() > 0) {
            throw new BussinessException(ErrorConstant.QUESTION_DELETE_HAS_OPTION);
        }
        super.delete(question);
    }

    /**
     * 编辑题目前的检查
     * 
     * @param question
     * @throws Exception
     */
    private void checkQuestion(Question question) throws Exception {
        Option opt = new Option();
        opt.setQuestion(question);
        List<Option> list = null;

        if (question.getType().equals(QuestionDAO.TYPE_TEXT)) {
            list = optionDao.findWithQuestion(opt);
            // 题目下已有选项，不能将题目修改为填写类型
            if (list.size() > 0) {
                throw new BussinessException(ErrorConstant.QUESTION_NOT_CHANGE_TO_TEXT);
            }
        } else if (question.getType().equals(QuestionDAO.TYPE_RADIO)) {
            opt.setIsright(OptionDAO.ISRIGHT_RIGHT);
            list = optionDao.findWithQuestion(opt);
            // 题目下已有多个正确，不能将题目修改为填写单选类型");
            if (list.size() > 1) {
                throw new BussinessException(ErrorConstant.QUESTION_NOT_CHANGE_TO_MULTI_SELECTED);
            }
        }
    }

    @Override
    public void add(Question entity) throws Exception {
        entity.setCreatetime(getSqlDate());

        super.add(entity);
    }

    @Override
    public void modify(Question entity) throws Exception {
        entity.setCreatetime(getSqlDate());
        checkQuestion(entity);
        super.modify(entity);
    }

    @Override
    public List<Question> findByExaminId(Integer id) {
        return getQuestionDao().findByExaminId(id);
    }

    public void setQuestionDao(QuestionDAO dao) {
        questionDao = dao;
    }

    public QuestionDAO getQuestionDao() {
        return questionDao;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected HibernateBaseDao<Question, Integer> getDao() {
        return (HibernateBaseDao<Question, Integer>) questionDao;
    }

    public OptionDAO getOptionDao() {

        return optionDao;
    }

    public void setOptionDao(OptionDAO optionDao) {

        this.optionDao = optionDao;
    }

    @Override
    public boolean checkOption(Question question, String[] options) {
        if (options == null)
            return false;

        boolean result = true;
        Set<Integer> rightOptions = new HashSet<Integer>();
        for (Option opt : question.getOptions()) {
            if (opt.getIsright().equals(OptionDAO.ISRIGHT_RIGHT)) {
                rightOptions.add(opt.getId());
            }
        }
        if (rightOptions.size() == options.length) {
            for (String str : options) {
                try {
                    if (rightOptions.add(Integer.parseInt(str))) {
                        result = false;
                    }
                } catch (Exception e) {
                    result = false;
                    log.error(e.getMessage(), e);
                }
            }
        } else {
            result = false;
        }
        return result;
    }

}
